import { decode, encode } from "cbor-x";

const origin = window.location.origin;

const BASE_URL = `${origin}/api`;

export class Resp {

    readonly resp: Response;

    constructor(resp: Response) {
        this.resp = resp;
    }

    async body() {
        return new Uint8Array(await this.resp.arrayBuffer());
    }

    async parse<T>() {
        const body = await this.body();
        return decode(body) as T;
    }
}

export interface ErrInfo {
    ec: number,
    msg: string,
}

const HEADER_RESP = "resp";
const RESP_OK = "ok";
const RESP_FAIL = "fail";

async function assertResp(resp: Response) {
    if (resp.status != 200) {
        throw `服务器通信错误:${resp.statusText}`;
    }
    const head = resp.headers.get(HEADER_RESP);
    if (head == null) {
        throw `head==null`;
    }
    if (head != RESP_OK) {
        const body = new Uint8Array(await resp.arrayBuffer());
        const errInfo = decode(body) as ErrInfo;
        throw errInfo;
    }
}

export interface PostReq<T> {
    url: string,
    body?: T | Uint8Array
}

export const http = {


    async get(url: string) {
        const resp = await fetch(`${BASE_URL}${url}`, {
            method: 'GET'
        });
        await assertResp(resp);
        return new Resp(resp);
    },

    async post<T>(req: PostReq<T>) {
        let buf: Uint8Array | null = null;
        if (req.body == undefined) {

        } else if (req.body instanceof Uint8Array) {
            buf = req.body;
        } else {
            buf = encode(req.body);
        }

        const resp = await fetch(`${BASE_URL}${req.url}`, {
            method: 'POST',
            body: buf
        });
        await assertResp(resp);
        return new Resp(resp);
    }
}

